<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;

/**
 * Class BookRule
 * @package App\Models
 */
class BookRule extends Model
{
    const SETTLED = 1;                      // 已结算订餐规则
    const NOT_SETTLED = 0;                  // 未结算订餐规则

    const CANCELED = 1;                     // 已取消
    const NOT_CANCELED = 0;                 // 未取消

    const EAT_TYPE_BREAKFAST = 1;           // 订餐类型 - 早餐
    const EAT_TYPE_LUNCH = 2;               // 订餐类型 - 午餐
    const EAT_TYPE_DINNER = 3;              // 订餐类型 - 晚餐

    protected $fillable = [
        'eat_date',
        'eat_type',
        'school_id'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function orders(){
        return $this->hasMany(BookOrder::class)->where('status',"<>",BookOrder::ORDER_STATUS_CANCELED);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsCanceled($query)
    {
        return $query->where('is_cancel', self::CANCELED);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsNotCanceled($query)
    {
        return $query->where('is_cancel', self::NOT_CANCELED);
    }

    /**
     * @param $query
     * @param User|null $user
     * @return mixed
     */
    public function scopeToUser($query , User $user = null){
        if (is_null($user)){
            $user = \Auth::user();
        }
        return $query->where("school_id",$user->school_id)
            ->whereIn('eat_type',$user->role->can_book_types);
    }

    /**
     * @param $query
     * @param $month
     * @return mixed
     */
    public function scopeMonth($query,$month){
        return $query->where("eat_date","like",$month."%");
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeAfterToday($query){
        return $query->where('eat_date',">=",now()->format("Y-m-d"));
    }

    /**
     * @return mixed|null
     * 类型label
     */
    public function getTypeLabelAttribute()
    {
        $typeLabels = [
            self::EAT_TYPE_BREAKFAST => '早餐',
            self::EAT_TYPE_LUNCH => '午餐',
            self::EAT_TYPE_DINNER => '晚餐',
        ];
        return $typeLabels[$this->eat_type] ?? null;
    }

    public function scopeSchoolIs($query, $schoolId)
    {
        $query->when($schoolId, function ($query) use ($schoolId) {
            $query->whereHas('school', function ($query) use ($schoolId) {
                $query->where('id', $schoolId);
            });
        });
    }

    public function scopeEatTypeIs($query, $eatType)
    {
        $query->when($eatType, function ($query) use ($eatType) {
            $query->where('eat_type', $eatType);
        });
    }

    public function scopeEatDateIs($query, $eatDate)
    {
        $query->when($eatDate, function ($query) use ($eatDate) {
            $query->where('eat_date', $eatDate);
        });
    }

    public function scopeIsCancel($query, $isCancel)
    {
        $query->when(!is_null($isCancel), function ($query) use ($isCancel) {
            $query->where('is_cancel', $isCancel);
        });
    }

    public function scopeIsSettled($query, $isSettled)
    {
        $query->when(!is_null($isSettled), function ($query) use ($isSettled) {
            $query->where('is_settled', $isSettled);
        });
    }

    /**
     * @return mixed
     */
    public function getUsersByRule()
    {
        $query = User::where('school_id', $this->school_id)->where('status', User::ACTIVE);
        if ($this->eat_type === self::EAT_TYPE_BREAKFAST) {
            $query->where('morning_rule', User::AUTOMATIC_ORDERING);
        } elseif ($this->eat_type === self::EAT_TYPE_LUNCH) {
            $query->where('lunch_rule', User::AUTOMATIC_ORDERING);
        } elseif ($this->eat_type === self::EAT_TYPE_DINNER) {
            $query->where('dinner_rule', User::AUTOMATIC_ORDERING);
        }
        return $query->get();
    }

    /**
     * @param $user
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getChildrenByRule($user)
    {
        $query = Child::query()->where('user_id', $user->id);
        if ($this->eat_type === self::EAT_TYPE_BREAKFAST) {
            $query->where('morning_rule', Child::AUTOMATIC_ORDERING);
        } elseif ($this->eat_type === self::EAT_TYPE_LUNCH) {
            $query->where('lunch_rule', Child::AUTOMATIC_ORDERING);
        } elseif ($this->eat_type === self::EAT_TYPE_DINNER) {
            $query->where('dinner_rule', Child::AUTOMATIC_ORDERING);
        }
        return $query->get();
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function prices()
    {
        return $this->hasMany(BookRulePrice::class, 'rule_id', 'id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function foods()
    {
        return $this->belongsToMany(Food::class, 'book_rule_foods', 'rule_id', 'food_id');
    }

    /**
     * @param $query
     * @return mixed
     * 早餐
     */
    public function scopeIsBreakfast($query)
    {
        return $query->where('eat_type', self::EAT_TYPE_BREAKFAST);
    }

    /**
     * @param $query
     * @return mixed
     * 中餐
     */
    public function scopeIsLunch($query)
    {
        return $query->where('eat_type', self::EAT_TYPE_LUNCH);
    }

    /**
     * @param $query
     * @return mixed
     * 午餐
     */
    public function scopeIsDinner($query)
    {
        return $query->where('eat_type', self::EAT_TYPE_DINNER);
    }

    /**
     * @return bool
     * 判断规则是否已过期
     */
    public function getIsActiveAttribute()
    {
        $tomorrow = now()->addDay(1)->format("Y-m-d");
        if ($this->eat_date == $tomorrow) {
            switch ($this->eat_type) {
                case self::EAT_TYPE_BREAKFAST:
                    $expireTime = $this->school->rule->morning_deadline;
                    break;
                case self::EAT_TYPE_LUNCH:
                    $expireTime = $this->school->rule->lunch_deadline;
                    break;
                case self::EAT_TYPE_DINNER:
                    $expireTime = $this->school->rule->dinner_deadline;
                    break;
            }
            if (date("H:i:s") < $expireTime) {
                return true;
            }
            return false;
        }
        if ($this->eat_date < $tomorrow) return false;
        return true;
    }

    /**
     * @return mixed
     * 获取星期
     */
    public function getWeekLabelAttribute()
    {
        $weeks = [
            0 => '周日',
            1 => '周一',
            2 => '周二',
            3 => '周三',
            4 => '周四',
            5 => '周五',
            6 => '周六'
        ];
        $day = Carbon::parse($this->eat_date)->dayOfWeek;
        return $weeks[$day];
    }

    /**
     * @return bool
     * 判断登录用户是否已定餐
     * 只能在小程序模块使用
     */
    public function getIsBookedAttribute()
    {
        $user = \Auth::user();
        $request = request();
        if ($user) {
            if ($request->id) {
                if ($user->isBookedByRule($this, $request->id)) {
                    return true;
                }
            } else {
                if ($user->isBookedByRule($this)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     * 关联学校
     */
    public function school()
    {
        return $this->belongsTo(School::class);
    }

    /**
     * @return mixed
     * 食物转字符串
     */
    public function getFoodsStringAttribute()
    {
        return $this->foods->implode('name', ',');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }

}

